home *** CD-ROM | disk | FTP | other *** search
/ Aminet 43 / Aminet 43 (2001)(GTI - Schatztruhe)[!][Jun 2001].iso / Aminet / comm / mail / YAM22src.lha / YAM.c < prev    next >
C/C++ Source or Header  |  2000-11-03  |  30KB  |  809 lines

  1. /***************************************************************************
  2.  
  3.  YAM - Yet Another Mailer
  4.  Copyright (C) 2000  Marcel Beck <mbeck@yam.ch>
  5.  
  6.  This program is free software; you can redistribute it and/or modify
  7.  it under the terms of the GNU General Public License as published by
  8.  the Free Software Foundation; either version 2 of the License, or
  9.  (at your option) any later version.
  10.  
  11.  This program is distributed in the hope that it will be useful,
  12.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  GNU General Public License for more details.
  15.  
  16.  You should have received a copy of the GNU General Public License
  17.  along with this program; if not, write to the Free Software
  18.  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20.  YAM Official Support Site :  http://www.yam.ch
  21.  YAM OpenSource project    :  http://sourceforge.net/projects/yamos/
  22.  
  23. ***************************************************************************/
  24.  
  25. #include "YAM.h"
  26. #include "YAM_rexx.h"
  27.  
  28. /***************************************************************************
  29.  Module: Root
  30. ***************************************************************************/
  31.  
  32. /// Global Vars
  33. //  Defines global variables and structures
  34. __near long __stack = 20000;
  35. __near long __buffsize = 8192;
  36. __near long __MemPoolPuddleSize = 16384;
  37. void __regargs __chkabort(void) {}
  38.  
  39. __near struct Library  *LocaleBase = NULL;
  40. struct Library *DataTypesBase, *MUIMasterBase, *XpkBase, *OpenURLBase, *SocketBase, *CManagerBase;
  41.  
  42. BOOL yamFirst = TRUE, yamLast = FALSE;
  43.  
  44. struct Global *G;
  45. struct Config *C, *CE;
  46.  
  47. char *Status[9] = { "U","O","F","R","W","E","H","S","N" };
  48. char *SigNames[3] = { ".signature", ".altsignature1", ".altsignature2" };
  49. char *FolderNames[4] = { "incoming", "outgoing", "sent", "deleted" };
  50.  
  51. char *ContType[MAXCTYPE+1] =
  52. {
  53.    /*CT_TX_PLAIN */ "text/plain",
  54.    /*CT_TX_HTML  */ "text/html",
  55.    /*CT_TX_GUIDE */ "text/x-aguide",
  56.    /*CT_AP_OCTET */ "application/octet-stream",
  57.    /*CT_AP_PS    */ "application/postscript",
  58.    /*CT_AP_RTF   */ "application/rtf",
  59.    /*CT_AP_LHA   */ "application/x-lha",
  60.    /*CT_AP_LZX   */ "application/x-lzx",
  61.    /*CT_AP_ZIP   */ "application/x-zip",
  62.    /*CT_AP_AEXE  */ "application/x-amiga-executable",
  63.    /*CT_AP_SCRIPT*/ "application/x-amigados-script",
  64.    /*CT_AP_REXX  */ "application/x-rexx",
  65.    /*CT_IM_JPG   */ "image/jpeg",
  66.    /*CT_IM_GIF   */ "image/gif",
  67.    /*CT_IM_PNG   */ "image/png",
  68.    /*CT_IM_TIFF  */ "image/tiff",
  69.    /*CT_IM_ILBM  */ "image/x-ilbm",
  70.    /*CT_AU_AU    */ "audio/basic",
  71.    /*CT_AU_8SVX  */ "audio/x-8svx",
  72.    /*CT_AU_WAV   */ "audio/x-wav",
  73.    /*CT_VI_MPG   */ "video/mpeg",
  74.    /*CT_VI_MOV   */ "video/quicktime",
  75.    /*CT_VI_ANIM  */ "video/x-anim",
  76.    /*CT_VI_AVI   */ "video/x-msvideo",
  77.    /*CT_ME_EMAIL */ "message/rfc822",
  78.    NULL,
  79. };
  80. APTR ContTypeDesc[MAXCTYPE] =
  81. {
  82.    MSG_CTtextplain, MSG_CTtexthtml, MSG_CTtextaguide,
  83.    MSG_CTapplicationoctetstream, MSG_CTapplicationpostscript, MSG_CTapplicationrtf, MSG_CTapplicationlha, MSG_CTapplicationlzx, MSG_CTapplicationzip, MSG_CTapplicationamigaexe, MSG_CTapplicationadosscript, MSG_CTapplicationrexx,
  84.    MSG_CTimagejpeg, MSG_CTimagegif, MSG_CTimagepng, MSG_CTimagetiff, MSG_CTimageilbm,
  85.    MSG_CTaudiobasic, MSG_CTaudio8svx, MSG_CTaudiowav,
  86.    MSG_CTvideompeg, MSG_CTvideoquicktime, MSG_CTvideoanim, MSG_CTvideomsvideo,
  87.    MSG_CTmessagerfc822
  88. };
  89. char *wdays[7] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
  90. char *months[12] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
  91. char *SecCodes[5] = { "none","sign","encrypt","sign+encrypt","anonymous" };
  92. ///
  93. /// Timer Class
  94. struct TC_Data
  95. {
  96.    struct MsgPort     *port;
  97.    struct timerequest *req;
  98. } TCData = { NULL,NULL };
  99.  
  100. //  Start a one second delay
  101. void TC_Start(void)
  102. {
  103.    TCData.req->tr_node.io_Command = TR_ADDREQUEST;
  104.    TCData.req->tr_time.tv_secs    = 1;
  105.    TCData.req->tr_time.tv_micro   = 0;
  106.    SendIO((struct IORequest *)TCData.req);
  107. }
  108.  
  109. //  Frees timer resources
  110. void TC_Exit(void)
  111. {
  112.    if (TCData.port)
  113.    {
  114.       if (TCData.req) 
  115.       {
  116.          if (CheckIO((struct IORequest *)TCData.req)) return;
  117.          AbortIO((struct IORequest *)TCData.req);
  118.          WaitIO((struct IORequest *)TCData.req);
  119.          CloseDevice((struct IORequest *)TCData.req);
  120.          DeleteExtIO((struct IORequest *)TCData.req);
  121.       }
  122.       DeleteMsgPort(TCData.port);
  123.    }
  124.    TCData.port = NULL;
  125.    TCData.req = NULL;
  126. }
  127.  
  128. //  Initializes timer resources
  129. BOOL TC_Init(void)
  130. {
  131.    if (TCData.port = CreateMsgPort())
  132.       if (TCData.req = (struct timerequest *)CreateExtIO(TCData.port, sizeof(struct timerequest)))
  133.          if (!OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)TCData.req, 0))
  134.             return TRUE;
  135.    return FALSE;
  136. }
  137.  
  138. //  Returns TRUE if the internal editor is currently being used
  139. BOOL TC_ActiveEditor(int wrwin)
  140. {
  141.    if (G->WR[wrwin])
  142.    {
  143.       APTR ao;
  144.       get(G->WR[wrwin]->GUI.WI, MUIA_Window_ActiveObject, &ao);
  145.       return (BOOL)(ao==G->WR[wrwin]->GUI.TE_EDIT);
  146.    }
  147.    return FALSE;
  148. }
  149.  
  150. //  Dispatcher for timer class (called once every second)
  151. void TC_Dispatcher(void)
  152. {
  153.    if (CheckIO((struct IORequest *)TCData.req))
  154.    {
  155.       int i;
  156.       WaitIO((struct IORequest *)TCData.req);
  157.       if (++G->SI_Count >= C->WriteIndexes && C->WriteIndexes)
  158.          if (!TC_ActiveEditor(0) && !TC_ActiveEditor(1))
  159.          {
  160.             MA_UpdateIndexes(FALSE);
  161.             G->SI_Count = 0;
  162.          }
  163.       if (++G->GM_Count >= C->CheckMailDelay*60 && C->CheckMailDelay)
  164.       {
  165.          for (i = 0; i < MAXWR; i++) if (G->WR[i]) break;
  166.          if (i == MAXWR && !G->CO)
  167.          {
  168.             MA_PopNow(POP_TIMED,-1);
  169.             G->GM_Count = 0;
  170.          }
  171.       }
  172.       for (i = 0; i < MAXWR; i++) if (G->WR[i]) if (++G->WR[i]->AS_Count >= C->AutoSave && C->AutoSave)
  173.       {
  174.          EditorToFile(G->WR[i]->GUI.TE_EDIT, WR_AutoSaveFile(i), NULL);
  175.          G->WR[i]->AS_Count = 0;
  176.          G->WR[i]->AS_Done = TRUE;
  177.       }
  178.       TC_Start();
  179.    }
  180. }
  181. ///
  182. /// AY_PrintStatus
  183. //  Shows progress of program initialization
  184. void AY_PrintStatus(char *txt, int percent)
  185. {
  186.    set(G->AY_Text, MUIA_Gauge_InfoText, txt);
  187.    set(G->AY_Text, MUIA_Gauge_Current, percent);
  188.    DoMethod(G->App, MUIM_Application_InputBuffered);
  189. }
  190. ///
  191. /// AY_SendMailFunc
  192. //  User clicked e-mail URL in About window
  193. SAVEDS void AY_SendMailFunc(void)
  194. {
  195.    int wrwin;
  196.    if (G->MA) if ((wrwin = MA_NewNew(NULL, 0)) >= 0)
  197.    {
  198.       setstring(G->WR[wrwin]->GUI.ST_TO, "Marcel Beck <support@yam.ch>");
  199.       set(G->WR[wrwin]->GUI.WI, MUIA_Window_ActiveObject, G->WR[wrwin]->GUI.ST_SUBJECT);
  200.    }
  201. }
  202. MakeHook(AY_SendMailHook, AY_SendMailFunc);
  203. ///
  204. /// AY_GoPageFunc
  205. //  User clicked homepage URL in About window
  206. SAVEDS void AY_GoPageFunc(void)
  207. {
  208.    GotoURL("http://www.yam.ch");
  209. }
  210. MakeHook(AY_GoPageHook, AY_GoPageFunc);
  211. ///
  212. /// AY_New
  213. //  Creates About window
  214. BOOL AY_New(BOOL hidden)
  215. {
  216.    char *text, logopath[SIZE_PATHFILE];
  217.    APTR ft_text, bt_sendmail, bt_gopage;
  218.  
  219.    strmfp(logopath, G->ProgDir, "Icons/logo");
  220.    G->AY_Win = WindowObject,
  221.       MUIA_Window_Title, GetStr(MSG_MA_About),
  222.       MUIA_Window_ID, MAKE_ID('C','O','P','Y'),
  223.       MUIA_Window_Activate, FALSE,
  224.       MUIA_HelpNode, "COPY",
  225.       WindowContents, VGroup,
  226.          MUIA_Background, MUII_GroupBack,
  227.          Child, HGroup,
  228.             MUIA_Group_Spacing, 0,
  229.             Child, HSpace(0),
  230.             Child, NewObject(CL_BodyChunk->mcc_Class,NULL,
  231.                MUIA_Bodychunk_File, logopath,
  232.             End,
  233.             Child, HSpace(0),
  234.          End,
  235.          Child, HCenter((VGroup,
  236.             Child, CLabel(GetStr(MSG_Copyright1)),
  237.             Child, ColGroup(2),
  238.                Child, bt_sendmail = TextObject,
  239.                   MUIA_Text_Contents, "\033c\033u\0335support@yam.ch",
  240.                   MUIA_InputMode, MUIV_InputMode_RelVerify,
  241.                End,
  242.                Child, bt_gopage = TextObject,
  243.                   MUIA_Text_Contents, "\033c\033u\0335http://www.yam.ch",
  244.                   MUIA_InputMode, MUIV_InputMode_RelVerify,
  245.                End,
  246.             End,
  247.             Child, RectangleObject,
  248.                MUIA_Rectangle_HBar, TRUE,
  249.                MUIA_FixHeight, 8,
  250.             End,
  251.             Child, ColGroup(2),
  252.                MUIA_Group_HorizSpacing, 8,
  253.                MUIA_Group_VertSpacing, 2,
  254.                Child, Label(GetStr(MSG_Version)),
  255.                Child, LLabel(__VERSION__),
  256.                Child, Label(GetStr(MSG_CompilationDate)),
  257.                Child, LLabel(__VERDATE__),
  258.              End,
  259.          End)),
  260.          Child, G->AY_Group = PageGroup,
  261.             Child, ListviewObject,
  262.                MUIA_Listview_Input, FALSE,
  263.                MUIA_Listview_List, ft_text = FloattextObject, ReadListFrame, End,
  264.             End,
  265.             Child, ScrollgroupObject,
  266.                MUIA_Scrollgroup_FreeHoriz, FALSE,
  267.                MUIA_Scrollgroup_Contents, VGroupV,
  268.                   InputListFrame,
  269.                   Child, G->AY_List = VGroup,
  270.                      Child, TextObject,
  271.                         MUIA_Text_Contents, GetStr(MSG_UserLogin),
  272.                         MUIA_Background,MUII_TextBack,
  273.                         MUIA_Frame     ,MUIV_Frame_Text,
  274.                         MUIA_Text_PreParse, MUIX_C MUIX_PH,
  275.                      End,
  276.                   End,
  277.                   Child, HVSpace,
  278.                End,
  279.             End,
  280.          End,
  281.          Child, G->AY_Text = GaugeObject,
  282.             GaugeFrame,
  283.             MUIA_Gauge_InfoText, " ",
  284.             MUIA_Gauge_Horiz, TRUE,
  285.          End,
  286.       End,
  287.    End;
  288.    if (G->AY_Win)
  289.    {
  290.       text = AllocStrBuf(SIZE_LARGE);
  291.       text = StrBufCat(text, GetStr(MSG_Copyright2));
  292.       text = StrBufCat(text, GetStr(MSG_UsedSoftware));
  293.       text = StrBufCat(text, "\0338Magic User Interface\0332 (Stefan Stuntz)\n"
  294.                              "\0338TextEditor.mcc, BetterString.mcc\0332 (Allan Odgaard)\n"
  295.                              "\0338Toolbar.mcc\0332 (Benny Kjær Nielsen)\n"
  296.                              "\0338Listtree.mcc\0332 (Klaus Melchior)\n"
  297.                              "\0338NList.mcc\0332 (Gilles Masson)\n"
  298.                              "\0338XPK\0332 (Urban Dominik Müller)\n\n");
  299.       text = StrBufCat(text, GetStr(MSG_WebSite));
  300.       set(ft_text, MUIA_Floattext_Text, text);
  301.       FreeStrBuf(text);
  302.       DoMethod(G->App, OM_ADDMEMBER, G->AY_Win);
  303.       DoMethod(bt_sendmail,MUIM_Notify,MUIA_Pressed,            FALSE,MUIV_Notify_Application,2,MUIM_CallHook,&AY_SendMailHook);
  304.       DoMethod(bt_gopage  ,MUIM_Notify,MUIA_Pressed,            FALSE,MUIV_Notify_Application,2,MUIM_CallHook,&AY_GoPageHook);
  305.       DoMethod(G->AY_Win  ,MUIM_Notify,MUIA_Window_CloseRequest,TRUE ,G->AY_Win              ,3,MUIM_Set,MUIA_Window_Open, FALSE);
  306.       set(G->AY_Win, MUIA_Window_Open, !hidden);
  307.       return TRUE;
  308.    }
  309.    return FALSE;
  310. }
  311. ///
  312. /// PopUp
  313. //  Un-iconify YAM
  314. void PopUp(void)
  315. {
  316.    int winopen;
  317.    nnset(G->App, MUIA_Application_Iconified,FALSE);
  318.    get(G->MA->GUI.WI, MUIA_Window_Open, &winopen);
  319.    if (!winopen) set(G->MA->GUI.WI, MUIA_Window_Open, TRUE);
  320.    DoMethod(G->MA->GUI.WI, MUIM_Window_ScreenToFront);
  321. }
  322. ///
  323. /// DoublestartHook
  324. //  A second copy of YAM was started
  325. SAVEDS void DoublestartFunc(void)
  326. {
  327.    PopUp();
  328. }
  329. MakeHook(DoublestartHook, DoublestartFunc);
  330. ///
  331. /// StayInProg
  332. //  Makes sure that the user really wants to quit the program
  333. BOOL StayInProg(void)
  334. {
  335.    BOOL req = FALSE;
  336.    int i, fq;
  337.  
  338.    if (G->AB->Modified || G->CO || C->ConfirmOnQuit) req = TRUE;
  339.    if (G->CO) req = TRUE;
  340.    for (i = 0; i < 4; i++) if (G->EA[i]) req = TRUE;
  341.    for (i = 0; i < 2; i++) if (G->WR[i]) req = TRUE;
  342.    get(G->App, MUIA_Application_ForceQuit, &fq); if (fq) req = FALSE;
  343.    if (!req) return FALSE;
  344.    return (BOOL)!MUI_Request(G->App, G->MA->GUI.WI, 0, GetStr(MSG_MA_ConfirmReq), GetStr(MSG_YesNoReq), GetStr(MSG_QuitYAMReq));
  345. }
  346. ///
  347. /// Root_GlobalDispatcher
  348. //  Processes return value of MUI_Application_NewInput
  349. BOOL Root_GlobalDispatcher(ULONG app_input)
  350. {
  351.    switch (app_input)
  352.    {
  353.       case MUIV_Application_ReturnID_Quit: return (BOOL)!StayInProg();
  354.       case ID_CLOSEALL: if (!C->IconifyOnQuit) return (BOOL)!StayInProg();
  355.                         set(G->App, MUIA_Application_Iconified, TRUE); break;
  356.       case ID_RESTART:  return 2;
  357.       case ID_ICONIFY:  MA_UpdateIndexes(FALSE); break;
  358.    }
  359.    return FALSE;
  360. }
  361. ///
  362. /// Root_New
  363. //  Creates MUI application
  364. BOOL Root_New(BOOL hidden)
  365. {
  366. #define MUIA_Application_UsedClasses 0x8042e9a7
  367.    static char *classes[] = { "TextEditor.mcc", "Toolbar.mcc", "BetterString.mcc", "InfoText.mcc", "Listtree.mcc", "NList.mcc", "NListviews.mcc", NULL };
  368.    G->App = ApplicationObject,
  369.       MUIA_Application_Author     ,"Marcel Beck",
  370.       MUIA_Application_Base       ,"YAM",
  371.       MUIA_Application_Title      ,"YAM",
  372.       MUIA_Application_Version    ,"$VER: YAM " __VERSION__ " (" __VERDATE__ ")",
  373.       MUIA_Application_Copyright  ,"© 1995-2000 by Marcel Beck",
  374.       MUIA_Application_Description,GetStr(MSG_AppDescription),
  375.       MUIA_Application_UseRexx    ,FALSE,
  376.       MUIA_Application_SingleTask ,!getenv("MultipleYAM"),
  377.       MUIA_Application_UsedClasses, classes,
  378.    End;
  379.    if (G->App)
  380.    {
  381.       set(G->App, MUIA_Application_HelpFile, "YAM.guide");
  382.       set(G->App, MUIA_Application_Iconified, hidden);
  383.       DoMethod(G->App, MUIM_Notify, MUIA_Application_DoubleStart, TRUE, MUIV_Notify_Application, 2, MUIM_CallHook, &DoublestartHook);
  384.       DoMethod(G->App, MUIM_Notify, MUIA_Application_Iconified, TRUE, MUIV_Notify_Application, 2, MUIM_Application_ReturnID, ID_ICONIFY);
  385.       if (AY_New(hidden)) return TRUE;
  386.    }
  387.    return FALSE;
  388. }
  389. ///
  390.  
  391. /// Terminate
  392. //  Deallocates used memory and MUI modules and terminates
  393. void Terminate(void)
  394. {
  395.    int i;
  396.    struct Folder **flist;
  397.  
  398.    if (G->CO) { CO_FreeConfig(CE); free(CE); DisposeModule(&G->CO); }
  399.    for (i = 0; i < MAXEA; i++) DisposeModule(&G->EA[i]);
  400.    for (i = 0; i < MAXRE; i++) if (G->RE[i]) { RE_CleanupMessage(i); DisposeModule(&G->RE[i]); }
  401.    for (i = 0; i <=MAXWR; i++) if (G->WR[i]) { WR_Cleanup(i); DisposeModule(&G->WR[i]); }
  402.    if (G->TR) { TR_Cleanup(); TR_CloseTCPIP(); }
  403.    DisposeModule(&G->FO);
  404.    DisposeModule(&G->FI);
  405.    DisposeModule(&G->ER);
  406.    DisposeModule(&G->US);
  407.    if (G->MA)
  408.    {
  409.       MA_UpdateIndexes(FALSE);
  410.       G->Weights[0] = GetMUI(G->MA->GUI.LV_FOLDERS, MUIA_HorizWeight);
  411.       G->Weights[1] = GetMUI(G->MA->GUI.LV_MAILS, MUIA_HorizWeight);
  412.       SaveLayout(TRUE);
  413.       set(G->MA->GUI.WI, MUIA_Window_Open, FALSE);
  414.       if (flist = FO_CreateList())
  415.       {
  416.          for (i = 1; i <= (int)*flist; i++) ClearMailList(flist[i], TRUE);
  417.          free(flist);
  418.       }
  419.    }
  420.    DisposeModule(&G->AB);
  421.    DisposeModule(&G->MA);
  422.    if (G->TTin) free(G->TTin);
  423.    if (G->TTout) free(G->TTout);
  424.    for (i = 0; i < MAXASL; i++) if (G->ASLReq[i]) MUI_FreeAslRequest(G->ASLReq[i]);
  425.    for (i = 0; i < MAXWR; i++) if (G->WR_NRequest[i].nr_stuff.nr_Msg.nr_Port) DeletePort(G->WR_NRequest[i].nr_stuff.nr_Msg.nr_Port);
  426.    if (G->AppIcon) RemoveAppIcon(G->AppIcon);
  427.    if (G->AppPort) DeletePort(G->AppPort);
  428.    if (G->RexxHost) CloseDownARexxHost(G->RexxHost);
  429.    TC_Exit();
  430.    if (G->App) MUI_DisposeObject(G->App);
  431.    for (i = 0; i < MAXICONS; i++) if (G->DiskObj[i]) FreeDiskObject(G->DiskObj[i]);
  432.    for (i = 0; i < MAXIMAGES; i++) if (G->BImage[i]) FreeBCImage(G->BImage[i]);
  433.    CO_FreeConfig(C);
  434.    ExitClasses();
  435.    if (DataTypesBase) CloseLibrary(DataTypesBase);
  436.    if (XpkBase)       CloseLibrary(XpkBase);
  437.    if (MUIMasterBase) CloseLibrary(MUIMasterBase);
  438.    CloseYAMCatalog();
  439.    if (G->Locale) CloseLocale(G->Locale);
  440.    if (LocaleBase) CloseLibrary(LocaleBase);
  441.    free(C); free(G);
  442.    if (yamLast) exit(0);
  443. }
  444. ///
  445. /// Abort
  446. //  Shows error requester, then terminates the program
  447. void Abort(char *error)
  448. {
  449.    if (error)
  450.       if (MUIMasterBase) MUI_Request(G->App ? G->App : NULL, NULL, 0, GetStr(MSG_ErrorStartup), GetStr(MSG_Quit), error);
  451.       else puts(error);
  452.    yamLast = TRUE;
  453.    Terminate();
  454. }
  455. ///
  456. /// InitLib
  457. //  Opens a library
  458. struct Library *InitLib(char *libname, int version, int revision, BOOL required, BOOL close)
  459. {
  460.    struct Library *lib = OpenLibrary(libname, version);
  461.    if (lib && revision) if (lib->lib_Version == version && lib->lib_Revision < revision) { CloseLibrary(lib); lib = NULL; }
  462.    if (!lib && required)
  463.    {
  464.       static char errorlib[SIZE_DEFAULT];
  465.       sprintf(errorlib, GetStr(MSG_ErrorLib), libname, version);
  466.       Abort(errorlib);
  467.    }
  468.    if (lib && close) CloseLibrary(lib);
  469.    return lib;
  470. }
  471. ///
  472. /// SetupAppIcons
  473. //  Sets location of mailbox status icon on workbench screen
  474. void SetupAppIcons(void)
  475. {
  476.    int i;
  477.    for (i = 0; i < 4; i++) if (G->DiskObj[i])
  478.    {
  479.       G->DiskObj[i]->do_CurrentX = C->IconPositionX;
  480.       G->DiskObj[i]->do_CurrentY = C->IconPositionY;
  481.    }
  482. }
  483. ///
  484. /// Initialise2
  485. //  Phase 2 of program initialization (after user logs in)
  486. void Initialise2(BOOL hidden)
  487. {
  488.    BOOL newfolders = FALSE;
  489.    int i;
  490.    struct Folder *folder, **oldfolders = NULL;
  491.  
  492.    AY_PrintStatus(GetStr(MSG_LoadingConfig), 30);
  493.    CO_SetDefaults(C, -1);
  494.    CO_LoadConfig(C, G->CO_PrefsFile, &oldfolders);
  495.    CO_Validate(C, FALSE);
  496.    AY_PrintStatus(GetStr(MSG_CreatingGUI), 40);
  497.    if (!(G->MA = MA_New()) || !(G->AB = AB_New())) Abort(GetStr(MSG_ErrorMuiApp));
  498.    MA_SetupDynamicMenus();
  499.    MA_ChangeSelectedFunc();
  500.    SetupAppIcons();
  501.    LoadLayout();
  502.    set(G->MA->GUI.LV_FOLDERS, MUIA_HorizWeight, G->Weights[0]);
  503.    set(G->MA->GUI.LV_MAILS,   MUIA_HorizWeight, G->Weights[1]);
  504.    AY_PrintStatus(GetStr(MSG_LoadingFolders), 50);
  505.    if (!FO_LoadTree(CreateFilename(".folders")) && oldfolders)
  506.    {
  507.       for (i = 0; i < 100; i++) if (oldfolders[i]) DoMethod(G->MA->GUI.NL_FOLDERS, MUIM_NList_InsertSingle, oldfolders[i], MUIV_NList_Insert_Bottom);
  508.       newfolders = TRUE;
  509.    }
  510.    if (oldfolders) { for (i = 0; oldfolders[i]; i++) free(oldfolders[i]); free(oldfolders); }
  511.    if (!FO_GetFolderByType(FT_INCOMING,NULL)) newfolders |= FO_CreateFolder(FT_INCOMING, FolderNames[0], GetStr(MSG_MA_Incoming));
  512.    if (!FO_GetFolderByType(FT_OUTGOING,NULL)) newfolders |= FO_CreateFolder(FT_OUTGOING, FolderNames[1], GetStr(MSG_MA_Outgoing));
  513.    if (!FO_GetFolderByType(FT_SENT    ,NULL)) newfolders |= FO_CreateFolder(FT_SENT    , FolderNames[2], GetStr(MSG_MA_Sent));
  514.    if (!FO_GetFolderByType(FT_DELETED ,NULL)) newfolders |= FO_CreateFolder(FT_DELETED , FolderNames[3], GetStr(MSG_MA_Deleted));
  515.    if (newfolders) FO_SaveTree(CreateFilename(".folders"));
  516.    AY_PrintStatus(GetStr(MSG_RebuildIndices), 60);
  517.    MA_UpdateIndexes(TRUE);
  518.    AY_PrintStatus(GetStr(MSG_LoadingFolders), 75);
  519.    for (i = 0; ; i++)
  520.    {
  521.       DoMethod(G->MA->GUI.NL_FOLDERS, MUIM_NList_GetEntry, i, &folder);
  522.       if (!folder) break;
  523.       if ((folder->Type == FT_INCOMING || folder->Type == FT_OUTGOING || folder->Type == FT_DELETED || C->LoadAllFolders) && !(folder->XPKType&1)) MA_GetIndex(folder);
  524.       else if (folder->Type != FT_SEPARATOR) folder->LoadedMode = MA_LoadIndex(folder, FALSE);
  525.       DoMethod(G->App, MUIM_Application_InputBuffered);
  526.    }
  527.    G->NewMsgs = -1;
  528.    MA_ChangeFolder(FO_GetFolderByType(FT_INCOMING,NULL));
  529.    AY_PrintStatus(GetStr(MSG_LoadingABook), 90);
  530.    AB_LoadTree(G->AB_Filename, FALSE, FALSE);
  531.    if (!(G->RexxHost = SetupARexxHost("YAM", NULL))) Abort(GetStr(MSG_ErrorARexx));
  532.    AY_PrintStatus("", 100);
  533.    set(G->MA->GUI.WI, MUIA_Window_Open, !hidden);
  534.    set(G->AY_Win, MUIA_Window_Open, FALSE);
  535.    set(G->AY_Text, MUIA_ShowMe, FALSE);
  536. }
  537. ///
  538. /// Initialise
  539. //  Phase 1 of program initialization (before user logs in)
  540. void Initialise(BOOL hidden)
  541. {
  542.    static char iconfile[SIZE_PATHFILE];
  543.    char iconpath[SIZE_PATH];
  544.    char *icnames[MAXICONS] = { "empty", "old", "new", "check" };
  545.    char *imnames[MAXIMAGES] = { "status_unread", "status_old", "status_forward",
  546.       "status_reply", "status_waitsend", "status_error", "status_hold",
  547.       "status_sent", "status_new", "status_delete", "status_download",
  548.       "status_group", "status_urgent", "status_attach", "status_report",
  549.       "status_crypt", "status_signed" };
  550.    int i;
  551.  
  552.    DateStamp(&G->StartDate);
  553.    if (LocaleBase = InitLib("locale.library", 38, 0, FALSE, FALSE)) G->Locale = OpenLocale(NULL);
  554.    OpenYAMCatalog();
  555.    MUIMasterBase = InitLib("muimaster.library", 19, 0, TRUE, FALSE);
  556.    InitLib("mui/Toolbar.mcc", 15, 6, TRUE, TRUE);
  557.    if (!InitClasses()) Abort(GetStr(MSG_ErrorClasses));
  558.    if (!Root_New(hidden)) Abort(FindPort("YAM") ? NULL : GetStr(MSG_ErrorMuiApp));
  559.    AY_PrintStatus(GetStr(MSG_InitLibs), 10);
  560.    XpkBase = InitLib(XPKNAME, 0, 0, FALSE, FALSE);
  561.    if (DataTypesBase = InitLib("datatypes.library", 39, 0, FALSE, FALSE))
  562.       if (InitLib("mui/Dtpic.mui", 0, 0, FALSE, TRUE)) G->DtpicSupported = TRUE;
  563.    if (!TC_Init()) Abort(GetStr(MSG_ErrorTimer));
  564.    for (i = 0; i < MAXASL; i++)
  565.       if (!(G->ASLReq[i] = MUI_AllocAslRequestTags(ASL_FileRequest, ASLFR_RejectIcons, TRUE,
  566.          TAG_END))) Abort(GetStr(MSG_ErrorAslStruct));
  567.    G->AppPort = CreatePort(NULL, 0);
  568.    for (i = 0; i < 2; i++)
  569.    {
  570.       G->WR_NRequest[i].nr_stuff.nr_Msg.nr_Port = CreatePort(NULL, 0);
  571.       G->WR_NRequest[i].nr_Name = (UBYTE *)G->WR_Filename[i];
  572.       G->WR_NRequest[i].nr_Flags = NRF_SEND_MESSAGE;
  573.    }
  574.    srand(time(NULL));
  575.    AY_PrintStatus(GetStr(MSG_LoadingGFX), 20);
  576.    strmfp(iconpath, G->ProgDir, "Icons");
  577.    for (i = 0; i < MAXICONS; i++)
  578.    {
  579.       strmfp(iconfile, iconpath, icnames[i]);
  580.       G->DiskObj[i] = GetDiskObject(iconfile);
  581.    }
  582.    for (i = 0; i < MAXIMAGES; i++)
  583.    {
  584.       strmfp(iconfile, iconpath, imnames[i]);
  585.       G->BImage[i] = LoadBCImage(iconfile);
  586.       DoMethod(G->App, MUIM_Application_InputBuffered);
  587.    }
  588. }
  589. ///
  590. /// SendWaitingMail
  591. //  Sends pending mail on startup
  592. void SendWaitingMail(void)
  593. {
  594.    struct Mail *mail;
  595.    BOOL doit = TRUE;
  596.    int tots = 0, hidden;
  597.    struct Folder *fo = FO_GetFolderByType(FT_OUTGOING, NULL);
  598.  
  599.    get(G->App, MUIA_Application_Iconified, &hidden);
  600.    for (mail = fo->Messages; mail; mail = mail->Next) if (mail->Status != STATUS_HLD) tots++;
  601.    if (!tots) return;
  602.    MA_ChangeFolder(fo);
  603.    if (!hidden) doit = MUI_Request(G->App, G->MA->GUI.WI, 0, NULL, GetStr(MSG_YesNoReq), GetStr(MSG_SendStartReq));
  604.    if (doit) MA_Send(SEND_ALL);
  605. }
  606. ///
  607. /// DoStartup
  608. //  Performs different checks/cleanup operations on startup
  609. void DoStartup(BOOL nocheck, BOOL hide)
  610. {
  611.  
  612.    if (C->CleanupOnStartup) DoMethod(G->App, MUIM_CallHook, &MA_DeleteOldHook);
  613.    if (C->RemoveOnStartup) DoMethod(G->App, MUIM_CallHook, &MA_DeleteDeletedHook);
  614.    if (C->CheckBirthdates && !nocheck && !hide) AB_CheckBirthdates();
  615.    if (TR_IsOnline())
  616.    {
  617.       if (C->GetOnStartup && !nocheck) { MA_PopNow(POP_START,-1); DisposeModule(&G->TR); }
  618.       if (C->SendOnStartup && !nocheck) { SendWaitingMail(); DisposeModule(&G->TR); }
  619.    }
  620. }
  621. ///
  622. /// Login
  623. //  Allows automatical login for AmiTCP-Genesis users
  624. void Login(char *user, char *password, char *maildir, char *prefsfile)
  625. {
  626.    struct Library *GenesisBase;
  627.    struct genUser *guser;
  628.    BOOL terminate = FALSE, loggedin = FALSE;
  629.  
  630.    if (GenesisBase = OpenLibrary("genesis.library", 1))
  631.    {
  632.       if (guser = GetGlobalUser())
  633.       {
  634.          terminate = !(loggedin = US_Login(guser->us_name, "\01", maildir, prefsfile));
  635.          FreeUser(guser);
  636.       }
  637.       CloseLibrary(GenesisBase);
  638.    }
  639.    if (!loggedin && !terminate) terminate = !US_Login(user, password, maildir, prefsfile);
  640.    if (terminate) Abort(NULL);
  641. }
  642. ///
  643. /// GetDST
  644. //  Checks if daylight saving time is active
  645. int GetDST(void)
  646. {
  647.    char *dst = getenv("SUMMERTIME");
  648.    int i;
  649.    if (!dst) return 0;
  650.    for (i = 0; i < 11; i++)
  651.    {
  652.       while (*dst != ':') if (!*dst++) return 0;
  653.       dst++;
  654.    }
  655.    return (*dst == 'Y' ? 2 : 1);
  656. }
  657. ///
  658.  
  659. /// Main
  660. //  Program entry point, main loop
  661. void main(int argc, char **argv)
  662. {
  663.    struct NewRDArgs nrda;
  664.    struct { STRPTR user;
  665.             STRPTR password;
  666.             STRPTR maildir;
  667.             STRPTR prefsfile;
  668.             LONG   nocheck;
  669.             LONG   hide;
  670.             LONG   debug;
  671.             STRPTR mailto;
  672.             STRPTR subject;
  673.             STRPTR letter;
  674.             STRPTR *attach;
  675.           } args = { NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL, NULL, NULL, NULL };
  676.    int wrwin, err, ret;
  677.    char **sptr, progdir[SIZE_PATH];
  678.    ULONG signals, appsigs, timsigs, notsigs0, notsigs1, rexsigs;
  679.    struct Message *msg;
  680.    struct User *user;
  681.    BPTR progdirlock, yamlock, oldcdirlock;
  682.  
  683.    nrda.Template = "USER/K,PASSWORD/K,MAILDIR/K,PREFSFILE/K,NOCHECK/S,HIDE/S,DEBUG/S,MAILTO/K,SUBJECT/K,LETTER/K,ATTACH/M";
  684.    nrda.ExtHelp = NULL;
  685.    nrda.Window = NULL;
  686.    nrda.Parameters = (LONG *)&args;
  687.    nrda.FileParameter = -1;
  688.    nrda.PrgToolTypesOnly = FALSE;
  689.    if (err = NewReadArgs((struct WBStartup *)(!argc && argv ? argv : 0), &nrda))
  690.    {
  691.       PrintFault(err, "YAM");
  692.       NewFreeArgs(&nrda);
  693.       exit(5); 
  694.    }
  695.    if (progdirlock = GetProgramDir())
  696.       NameFromLock(progdirlock, progdir, SIZE_PATH);
  697.    else
  698.    {
  699.       strcpy(progdir, "YAM:");
  700.       SetProgramDir(Lock(progdir, ACCESS_READ));
  701.    }
  702.    yamlock = Lock(progdir, ACCESS_READ);
  703.    oldcdirlock = CurrentDir(yamlock);
  704.    while (1)
  705.    {
  706.       DataTypesBase = MUIMasterBase = XpkBase = OpenURLBase = SocketBase = NULL;
  707.       G = calloc(1,sizeof(struct Global));
  708.       C = calloc(1,sizeof(struct Config));
  709.       strcpy(G->ProgDir, progdir);
  710.       if (!args.maildir) strcpy(G->MA_MailDir, progdir);
  711.       args.hide = -args.hide; args.nocheck = -args.nocheck;
  712.       G->TR_Debug = -args.debug;
  713.       G->TR_Allow = TRUE;
  714.       G->CO_DST = GetDST();
  715.       if (yamFirst)
  716.       {
  717.          Initialise(args.hide);
  718.          Login(args.user, args.password, args.maildir, args.prefsfile);
  719.          Initialise2(args.hide);
  720.          DoMethod(G->App, MUIM_Application_Load, MUIV_Application_Load_ENVARC);
  721.          AppendLog(0, GetStr(MSG_LOG_Started), "", "", "", "");
  722.          MA_StartMacro(MACRO_STARTUP, NULL);
  723.          DoStartup(args.nocheck, args.hide);
  724.          if (args.mailto || args.letter || args.subject || args.attach) if ((wrwin = MA_NewNew(NULL, 0)) >= 0)
  725.          {
  726.             if (args.mailto) setstring(G->WR[wrwin]->GUI.ST_TO, args.mailto);
  727.             if (args.subject) setstring(G->WR[wrwin]->GUI.ST_SUBJECT, args.subject);
  728.             if (args.letter) FileToEditor(args.letter, G->WR[wrwin]->GUI.TE_EDIT);
  729.             if (args.attach) for (sptr = args.attach; *sptr; sptr++)
  730.                if (FileSize(*sptr) >= 0) WR_AddFileToList(wrwin, *sptr, NULL, FALSE);
  731.          }
  732.          yamFirst = FALSE;
  733.       }
  734.       else
  735.       {
  736.          Initialise(FALSE);
  737.          Login(NULL, NULL, NULL, NULL);
  738.          Initialise2(FALSE);
  739.          DoMethod(G->App, MUIM_Application_Load, MUIV_Application_Load_ENVARC);
  740.       }
  741.       user = US_GetCurrentUser();
  742.       AppendLogNormal(1, GetStr(MSG_LOG_LoggedIn), user->Name, "", "", "");
  743.       AppendLogVerbose(1, GetStr(MSG_LOG_LoggedInVerbose), user->Name, G->CO_PrefsFile, G->MA_MailDir, "");
  744.       TC_Start();
  745.       appsigs  = 1<<G->AppPort->mp_SigBit;
  746.       timsigs  = 1<<TCData.port->mp_SigBit;
  747.       notsigs0 = 1<<G->WR_NRequest[0].nr_stuff.nr_Msg.nr_Port->mp_SigBit;
  748.       notsigs1 = 1<<G->WR_NRequest[1].nr_stuff.nr_Msg.nr_Port->mp_SigBit;
  749.       rexsigs  = 1<<G->RexxHost->port->mp_SigBit;
  750.       while (!(ret = Root_GlobalDispatcher(DoMethod(G->App, MUIM_Application_NewInput, &signals))))
  751.       {
  752.          if (signals)
  753.          {
  754.             signals = Wait(signals | timsigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | appsigs | notsigs0 | notsigs1 | rexsigs);
  755.             if (signals & SIGBREAKF_CTRL_C) break;
  756.             if (signals & SIGBREAKF_CTRL_F) PopUp();
  757.             if (signals & timsigs) TC_Dispatcher();
  758.             if (signals & rexsigs) ARexxDispatch(G->RexxHost);
  759.             if (signals & appsigs)
  760.             {
  761.                struct AppMessage *apmsg;
  762.                while (apmsg = (struct AppMessage *)GetMsg(G->AppPort))
  763.                {
  764.                   if (apmsg->am_Type == AMTYPE_APPICON)
  765.                   {
  766.                      PopUp();
  767.                      if (apmsg->am_NumArgs)
  768.                      {
  769.                         int wrwin;
  770.                         if      (G->WR[0]) wrwin = 0;
  771.                         else if (G->WR[1]) wrwin = 1;
  772.                         else wrwin = MA_NewNew(NULL, 0);
  773.                         if (wrwin >= 0) WR_App(wrwin, apmsg);
  774.                      }
  775.                   }
  776.                   ReplyMsg((struct Message *)apmsg);
  777.                }
  778.             }
  779.             if (signals & notsigs0)
  780.             {
  781.                while (msg = GetMsg(G->WR_NRequest[0].nr_stuff.nr_Msg.nr_Port)) ReplyMsg(msg);
  782.                if (G->WR[0]) FileToEditor(G->WR_Filename[0], G->WR[0]->GUI.TE_EDIT);
  783.             }
  784.             if (signals & notsigs1)
  785.             {
  786.                while (msg = GetMsg(G->WR_NRequest[1].nr_stuff.nr_Msg.nr_Port)) ReplyMsg(msg);
  787.                if (G->WR[1]) FileToEditor(G->WR_Filename[1], G->WR[1]->GUI.TE_EDIT);
  788.             }
  789.          }
  790.       }
  791.       if (C->SendOnQuit && !args.nocheck) if (TR_IsOnline()) SendWaitingMail();
  792.       if (C->CleanupOnQuit) DoMethod(G->App, MUIM_CallHook, &MA_DeleteOldHook);
  793.       if (C->RemoveOnQuit) DoMethod(G->App, MUIM_CallHook, &MA_DeleteDeletedHook);
  794.       if (ret == 1)
  795.       {
  796.          yamLast = TRUE;
  797.          AppendLog(99, GetStr(MSG_LOG_Terminated), "", "", "", "");
  798.          MA_StartMacro(MACRO_QUIT, NULL);
  799.          CurrentDir(oldcdirlock);
  800.          UnLock(yamlock);
  801.          NewFreeArgs(&nrda);
  802.       }
  803.       FreeData2D(&Header);
  804.       Terminate();
  805.    }
  806. }
  807. ///
  808.  
  809.